/*
 * Copyright © Yan Zhenjie. All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sensetime.myandserver.response;

import android.os.Environment;
import android.util.Log;

import com.yanzhenjie.andserver.RequestHandler;
import com.yanzhenjie.andserver.upload.HttpFileUpload;
import com.yanzhenjie.andserver.upload.HttpUploadContext;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HttpContext;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * <p>Upload file handler.</p>
 * Created by Yan Zhenjie on 2016/6/13.
 */
public class RequestUploadHandler implements RequestHandler {

    @Override
    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
        // HttpFileUpload.isMultipartContent(request) // DELETE、PUT、POST method。

        if (!HttpFileUpload.isMultipartContentWithPost(request)) { // Is POST and upload.
            response(403, "You must upload file.", response);
        } else {
            // File save directory.
            final File saveDirectory = Environment.getExternalStorageDirectory();

            if (saveDirectory.isDirectory()) {
                try {
                    processFileUpload(request, saveDirectory);
                    byte[] info = "0,0.98,1".getBytes();
                    byte[] info2 = new byte[200];
                    System.arraycopy(info,0,info2,0,info.length);
                    byte[] img = file2byte(Environment.getExternalStorageDirectory().getAbsolutePath() + "/timg.jpg");
                    byte[] resp = byteMerger(info2,img);
                    response(200, resp, response);
                } catch (Exception e) {
                    e.printStackTrace();
                    response(500, "Save the file when the error occurs.", response);
                }
            } else {
                response(500, "The server can not save the file.", response);
            }
        }
    }

    private void response(int responseCode, String message, HttpResponse response) throws IOException {
        response.setStatusCode(responseCode);
        response.setEntity(new StringEntity(message, "utf-8"));
    }

    private void response(int responseCode, byte[] message, HttpResponse response) throws IOException {
        response.setStatusCode(responseCode);
        response.setEntity(new ByteArrayEntity(message));
    }

    /**
     * Parse file and save.
     *
     * @param request       request.
     * @param saveDirectory save directory.
     * @throws Exception may be.
     */
    private void processFileUpload(HttpRequest request, File saveDirectory) throws Exception {
        FileItemFactory factory = new DiskFileItemFactory(1024 * 1024, saveDirectory);
        HttpFileUpload fileUpload = new HttpFileUpload(factory);

        // Set upload process listener.
        // fileUpload.setProgressListener(new ProgressListener(){...});

        List<FileItem> fileItems = fileUpload.parseRequest(new HttpUploadContext((HttpEntityEnclosingRequest) request));

        for (FileItem fileItem : fileItems) {
            if (!fileItem.isFormField()) { // File param.
                // Attribute.
                // fileItem.getContentType();
                // fileItem.getFieldName();
                // fileItem.getName();
                // fileItem.getSize();
                // fileItem.getString();

//                File uploadedFile = new File(saveDirectory, fileItem.getName());
//                // 把流写到文件上。
//                fileItem.write(uploadedFile);

                byte[] bytes = fileItem.get();
                byte[] info = new byte[200];
                byte[] img = new byte[bytes.length - 200];
                System.arraycopy(bytes,0,info,0,200);
                System.arraycopy(bytes,200,img,0,img.length);
                Log.d("liuyi", "processFileUpload: " + new String(info,"UTF-8"));
                File uploadedFile = new File(saveDirectory, fileItem.getName());
                createFileWithByte(img);
            } else { // General param.
                String key = fileItem.getName();
                String value = fileItem.getString();
            }
        }
    }

    private byte[] byteMerger(byte[] byte_1, byte[] byte_2){
        byte[] byte_3 = new byte[byte_1.length+byte_2.length];
        System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
        System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
        return byte_3;
    }

    private void createFileWithByte(byte[] bytes) {
        // TODO Auto-generated method stub
        /**
         * 创建File对象，其中包含文件所在的目录以及文件的命名
         */
        File file = new File(Environment.getExternalStorageDirectory(),"ccc.bmp");
        // 创建FileOutputStream对象
        FileOutputStream outputStream = null;
        // 创建BufferedOutputStream对象
        BufferedOutputStream bufferedOutputStream = null;
        try {
            // 如果文件存在则删除
            if (file.exists()) {
                file.delete();
            }
            // 在文件系统中根据路径创建一个新的空文件
            file.createNewFile();
            // 获取FileOutputStream对象
            outputStream = new FileOutputStream(file);
            // 获取BufferedOutputStream对象
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            // 往文件所在的缓冲输出流中写byte数据
            bufferedOutputStream.write(bytes);
            // 刷出缓冲输出流，该步很关键，要是不执行flush()方法，那么文件的内容是空的。
            bufferedOutputStream.flush();
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
        } finally {
            // 关闭创建的流对象
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }

    private byte[] file2byte(String filePath)
    {
        byte[] buffer = null;
        try
        {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return buffer;
    }
}
